﻿using System;
using System.Data;
using System.Collections.Generic;
using System.Windows.Forms;
using SdmxMl.Common;
using SdmxMl.Structure;
using SdmxMl.Panels;

namespace SdmxMl.UC
{
    public partial class UcBaseSetMap : UserControl
    {
        #region Internal Members

        private UcMlText ucMlText = null;
        private StrSetMapItemList mapSet;
        private PanelAnnotationList pannelAnnot;
        private bool _isFinal;
        private int lastCol;
        private int lastRow;

        #endregion

        public UcBaseSetMap()
        {
            InitializeComponent();
            ucMlText = new UcMlText();
            customComboBoxName.DropDownControl = ucMlText;

            ucEditReferenceSrc.LabelRef = "Source Ref. Id";
            ucEditReferenceDst.LabelRef = "Target Ref. Id";
            ucEditReferenceSrc.ReferenceSelect += new EventHandler(ucEditReference_ReferenceSelect);
            ucEditReferenceDst.ReferenceSelect += new EventHandler(ucEditReference_ReferenceSelect);
        }

        public void BindMap(StrSetMapItemList mil, PanelAnnotationList pA, bool isFinal)
        {
            lastCol = lastRow = -1;
            mapSet = mil;
            pannelAnnot = pA;
            _isFinal = isFinal;

            IsFinalEditControls(isFinal);

            if (mapSet != null)
            {
                textBoxID.Text = mapSet.Info.Id;
                ucMlText.ML = mapSet.Info.Name;
                customComboBoxName.Text = mapSet.Info.Name.ToString();

                comboMultiLinesDescr.Text = mapSet.Info.Description.ToString();
                comboMultiLinesDescr.ML = mapSet.Info.Description;
                
                ucEditReferenceSrc.AtrefactType = mapSet.ArtType;
                ucEditReferenceSrc.ArtefactRef = new ArtefactRefBase(mapSet.SourceRef.FullIdent);

                ucEditReferenceDst.AtrefactType = mapSet.ArtType;
                ucEditReferenceDst.ArtefactRef = new ArtefactRefBase(mapSet.TargetRef.FullIdent);
                dataGridViewInfo.DataSource = mapSet.GetMapTable();
            }

            pannelAnnot.BindFromNode(mapSet.Info, isFinal);

        }

        void ucEditReference_ReferenceSelect(object sender, EventArgs e)
        {
            //    ucr == ucEditReferenceDst && ucr.ArtefactRef.FullIdent != mapSet.TargetRef.FullIdent)
            UcEditReference ucr = sender as UcEditReference;
            if (ucr == ucEditReferenceSrc && ucr.ArtefactRef.FullIdent != mapSet.SourceRef.FullIdent)
                UpdateReference(ucr, mapSet.SourceRef);
            else if (ucr == ucEditReferenceDst && ucr.ArtefactRef.FullIdent != mapSet.TargetRef.FullIdent)
                UpdateReference(ucr, mapSet.TargetRef);
        }

        private void UpdateReference(UcEditReference ucr, ArtefactRefBase refBase)
        {
            bool updateReference = true;
            if (mapSet.Count > 0)
            {
                if (MessageBox.Show(this, "Reset existing Map?", "Confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
                {
                    // Reset to previous references
                    ucr.ArtefactRef = new ArtefactRefBase(refBase.FullIdent);
                    updateReference = false;
                }
            }
            if (updateReference)
            {
                // Clear old mapping
                mapSet.Clear();
                dataGridViewInfo.DataSource = mapSet.GetMapTable();
                // Store new reference
                refBase.Id = ucr.ArtefactRef.Id;
                refBase.AgencyId = ucr.ArtefactRef.AgencyId;
                refBase.Version = ucr.ArtefactRef.Version;
            }
        }

        // No edition if Parent Artefact IsFinal
        private void IsFinalEditControls(bool isFinal)
        {
            bool enabled = isFinal == false;

            textBoxID.ReadOnly = isFinal;
            customComboBoxName.IsFinal = isFinal;
            comboMultiLinesDescr.IsFinal = isFinal;

            ucEditReferenceSrc.Enabled = ucEditReferenceDst.Enabled = enabled;
        }

        public void BindFromControls()
        {
            if (mapSet != null)
            {
                mapSet.Info.Id = textBoxID.Text;
                mapSet.Info.Name.UpdateForCurrentLanguage(customComboBoxName.Text);
                mapSet.Info.Description.UpdateForCurrentLanguage(comboMultiLinesDescr.Text);
            }
       }

        private void butAdd_Click(object sender, System.EventArgs e)
        {
            try
            {
                DlgSetMap aDlg = new DlgSetMap(mapSet);
                aDlg.ShowDialog(this);
                dataGridViewInfo.DataSource = mapSet.GetMapTable();

            }
            catch (Exception ex)
            {
                MessageBox.Show(this, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

        }
        private DataRow FindSelectedRow()
        {
            DataRow findRow = null;
            if (dataGridViewInfo.DataSource != null && dataGridViewInfo.CurrentRow != null)
            {
                DataRowView drv = dataGridViewInfo.CurrentRow.DataBoundItem as DataRowView;
                if (drv != null)
                    findRow = drv.Row;
            }

            return findRow;
        }

        private void butRemove_Click(object sender, EventArgs e)
        {
            try
            {
                DataRow findRow = FindSelectedRow();
                if (findRow != null && mapSet != null)
                {
                    //  if (MessageBox.Show(this, "Erase selected correspondance?", "Confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                    {

                        // locate 
                        StrSetMapItem toRemove = new StrSetMapItem(findRow["Source"].ToString(), findRow["Target"].ToString(), string.Empty);
                        mapSet.RemoveItem(toRemove);

                        //Remove it on grid too
                        (dataGridViewInfo.DataSource as DataTable).Rows.Remove(findRow);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(this, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void dataGridViewInfo_SelectionChanged(object sender, EventArgs e)
        {
            try
            {
                int i = dataGridViewInfo.SelectedCells.Count;
                if (i > 0)
                {
                    int col = dataGridViewInfo.SelectedCells[0].ColumnIndex;
                    int row = dataGridViewInfo.SelectedCells[0].RowIndex;
                    string code = string.Empty;
                    List<string> listCorr = null;

                    if (col != lastCol || row != lastRow)
                    {
                        circleTreeMap.Clear();
                        // 0 - 1 gives source for circle
                        if (col < 2)
                        {
                            code = dataGridViewInfo.Rows[row].Cells[0].Value.ToString();
                            listCorr = mapSet.GetTargetArrayForSource(code);
                            DrawCircles(listCorr, 2, code);

                        }
                        // 3 and more gives target for circle
                        else if (col > 2)
                        {
                            code = dataGridViewInfo.Rows[row].Cells[3].Value.ToString();
                            listCorr = mapSet.GetSourceArrayForTarget(code);
                            DrawCircles(listCorr, 0, code);
                        }
                    }
                }
            }
            catch
            {
                MessageBox.Show(this, "Unable to draw relations of item");

            }
        }

        private void DrawCircles(List<string> list, int indexList, string valAlone)
        {
            int indexVal = indexList == 0 ? 2 : Math.Max(0, indexList - 2);
            int yval = list.Count / 2;

            circleTreeMap.BeginUpdate();
            circleTreeMap.Add(indexVal, yval, valAlone);

            int y = 0;
            foreach (string s in list)
            {
                circleTreeMap.Add(indexList, y, s);
                circleTreeMap.AddLink(indexVal, yval, indexList, y, s);
                y++;
            }
            circleTreeMap.EndUpdate();

        }

    }
}
